﻿using System;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Threading;
using System.Collections.Generic;

namespace SocketTestCSSever {

	class User {
		public TcpClient client { get; private set; }
		public BinaryReader br { get; private set; }
		public BinaryWriter bw { get; private set; }
		public string userName { get; set; }
		public User (TcpClient client) {
			this.client = client;
			NetworkStream networkStream = client.GetStream ();
			br = new BinaryReader (networkStream);
			bw = new BinaryWriter (networkStream);
		}

		public void Close () {
			br.Close ();
			bw.Close ();
			client.Close ();
		}
	}

	class MainServer {
		private const int port = 9999;
		private TcpListener myListener;
		private IPAddress localAddress;
		private bool isNormalExit = false;
		private List<User> userList = new List<User> ();

		public MainServer () {
			localAddress = IPAddress.Parse ("127.0.0.1");
			myListener = new TcpListener (localAddress, port);
		}


		public void StartSever () {
			myListener.Start ();
			Thread myThread = new Thread (ListenClientConnect);
			myThread.Start ();
		}

		private void ListenClientConnect () {
			TcpClient newClient = null;

			while (true) {
				try {
					newClient = myListener.AcceptTcpClient ();
				} catch {
					break;
				}

				Console.WriteLine ("客户端连接成功");
				User user = new User (newClient);
				Thread threadReceive = new Thread (ReceiveData);
				threadReceive.Start (user);
			}
		}

		private void ReceiveData (object userState) {
			User user = (User)userState;
			TcpClient client = user.client;
			while (isNormalExit == false) {
				string receiveString = null;
				try {
					receiveString = user.br.ReadString ();
				} catch {
					if (isNormalExit == false) {
						RemoveUser (user);
					}
					break;
				}

				string [] splitString = receiveString.Split (',');
				switch (splitString[0]) {
					case "Login":
					user.userName = splitString [1];
					Console.WriteLine (user.userName + "登录成功");
					SendToAllClient (user, receiveString);
					break;
					case "Logout":
					Console.WriteLine (user.userName + "登出成功");
					SendToAllClient (user, receiveString);
					RemoveUser (user);
					return;
					case "Talk":
					string talkstring = receiveString.Substring (splitString [0].Length + splitString [1].Length + 2);
					SendToClient (user, "talk," + user.userName + "," + talkstring);
					foreach (User target in userList) {
						if (target.userName == splitString[1] && user.userName != splitString[1]) {
							SendToClient (target, "talk," + user.userName + "," + talkstring);
							break;
						}
					}
					break;
					default:
					Console.WriteLine ("not format: " + receiveString);
					break;
				}

			}
		}

		private void SendToAllClient (User user, string message) {
			string command = message.Split (',') [0].ToLower ();
			if (command == "login") {
				for (int i = 0; i < userList.Count; i++) {
					SendToClient (userList[i], message);
					if (userList [i].userName != user.userName) {
						SendToClient (user, "login," + userList [i].userName);
					}

				}
			} else if (command == "logout") {
				for (int i = 0; i < userList.Count; i++) {
					if (userList [i].userName != user.userName) {
						SendToClient (userList [i], message);
					}
				}
			}
		}

		private void SendToClient (User user, string message) {
			try {
				user.bw.Write (message);
				user.bw.Flush ();
				Console.WriteLine (string.Format("向 {0} 发送： {1}", user.userName, message));
			} catch {
				Console.WriteLine (string.Format ("向 {0} 发送消息失败", user.userName));
			}
		}

		private void RemoveUser (User user) {
			userList.Remove (user);
			user.Close ();
			Console.WriteLine ("the count of current users :" + userList.Count);
		}
	}



	public class SyncChatServer {
		public SyncChatServer () {
		}

		public static void Main1 (string [] args) {

			var server = new MainServer ();
			server.StartSever ();

			Console.WriteLine ("hello SyncChatServer");
		}
	}
}
